昨天我們針對聲音訊號的基本處理做了一些簡單的介紹,知道了聲音是一連串隨著時間變化的訊號所組成的,同時可以透過傅立葉分析的方式來得到同一個時刻不同音高成分的分佈。今天我們會再針對不同的音高去做進一步的討論
我們知道聲音比較高的頻率對應的就是頻率比較高的聲音,但對於不同頻率的聲音聽起來差多少呢?這邊就要提到了人類對於不同音調之間感受度的假設:
人類對於低頻率聲音之間的分辨力較好,對高頻率之間的分辨力較差。
上面這個看起來似乎有點難理解,我這邊舉一個例子好了:
假設你今天口袋只有100塊錢,掉了10塊錢對你來說感覺會很心痛
但如果你今天口袋有10000塊錢,那掉了10塊前的感覺就會小得多
根據前面的結論,因此我們會期待有一種方式
因此這邊我們用了數組隨著頻率分佈越高就越廣的濾波器來對原始聲音訊號做轉換,就可以將本來的訊號用非常少的尺寸儲存,並且可以有對於不同時刻頻率分佈的特徵
mfccs = librosa.feature.mfcc(y=sound, sr=sr, n_mfcc=12)# librosa有有內建轉換函數
print("原始訊號尺寸:", sound.shape)
print("轉換成mfcc尺寸:", mfccs.shape)
輸出:
原始訊號尺寸: (393330,)
轉換成mfcc尺寸: (12, 769)
繪製一下mfcc強度圖
import seaborn as sns
sns.heatmap(mfccs).invert_yaxis()
輸出:
前面提到了我們可以針對不同的頻率去做不同解析度的filter來取得特徵,那這邊再提及另一個角度的調整,這邊的思考角度來自於我們在做STFT的時候會需要有一個時間窗口來轉換一段時間變成一段頻率的分佈,但其實對於不同頻率的聲音我們要取得有效的轉換所需的長度又不太一樣,因此就提出了具有以下特性的常數Q轉換(Constant Q Transfrom):
正是因為這樣的特性,對於現代大多數基於十二平均律的音樂來是非常適合的。
import numpy as np
cqts = librosa.cqt(y=sound, sr=sr,pad_mode='wrap') # 常數Q轉換
cqts_abs = np.abs(cqts)
# 繪製一下CQT轉換強度圖
fig, ax = plt.subplots()
img = librosa.display.specshow(librosa.amplitude_to_db(cqts_abs, ref=np.max),
sr=sr, x_axis='time', y_axis='cqt_note', ax=ax)
ax.set_title('Constant-Q power spectrum')
fig.colorbar(img, ax=ax, format="%+2.0f dB")
輸出: